package com.huluobo.a2109kotlinshopping.order

import android.annotation.SuppressLint
import android.content.Intent
import android.hardware.biometrics.BiometricPrompt
import android.os.Build
import android.os.CancellationSignal
import android.os.Handler
import android.os.Message
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
import com.alipay.sdk.app.EnvUtils
import com.alipay.sdk.app.PayTask
import com.blankj.utilcode.util.ToastUtils
import com.huluobo.a2109kotlinshopping.R
import com.huluobo.a2109kotlinshopping.base.BaseMVVMActivity
import com.huluobo.a2109kotlinshopping.databinding.ActivityPayBinding
import com.huluobo.a2109kotlinshopping.db.DatabaseUtil
import com.huluobo.a2109kotlinshopping.pay.PayResult
import com.huluobo.a2109kotlinshopping.pay.util.OrderInfoUtil2_0


class PayActivity : BaseMVVMActivity<ActivityPayBinding>() {
    //生物识别传感器
    private lateinit var biometricPrompt: BiometricPrompt

    //取消的签名
    private lateinit var cancellationSignal: CancellationSignal

    override fun initData() {
    }

    override fun initView() {
        //取出数据库中订单列表
        val queryOrder = DatabaseUtil.getDb().orderDao().queryOrder()

        //总价
        var totalPrice = 0
        queryOrder.forEach {
            totalPrice += it.goods_default_price * it.count
        }
        dataBinding.payPrice.text = "￥${totalPrice}.00元"

        dataBinding.payCancel.setOnClickListener {
            //点击取消支付时,需要将订单中所有信息销毁,因为还没有生成订单
            DatabaseUtil.getDb().orderDao().deleteAllOrder()
            finish()
        }

        //指纹识别初始化
        //需要api大于28才有传感器的sdk,正常需要29才能进行指纹识别
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            biometricPrompt = BiometricPrompt.Builder(this)
                .setTitle("指纹支付")
                .setNegativeButton(
                    "取消", mainExecutor
                ) { dialog, which -> ToastUtils.showLong("取消支付") }
                .build()
        }

        cancellationSignal = CancellationSignal()
        cancellationSignal.setOnCancelListener {
            ToastUtils.showLong("取消支付")
        }

        //指纹支付
        fun pointPay() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                biometricPrompt.authenticate(
                    cancellationSignal,
                    mainExecutor,
                    object : BiometricPrompt.AuthenticationCallback() {
                        override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult?) {
                            super.onAuthenticationSucceeded(result)
                            //生物识别成功
                            pay()
                        }
                    })
            };
        }

        dataBinding.payButton.setOnClickListener {
            pointPay()
        }

        //初始化支付宝沙盒
        EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);

    }

    override fun getLayoutId(): Int = R.layout.activity_pay

    //支付宝相关
    /**
     * 用于支付宝支付业务的入参 app_id。
     */
    val APPID = "2016103000779553"

    /**
     * 用于支付宝账户登录授权业务的入参 pid。
     */
    val PID = ""

    /**
     * 用于支付宝账户登录授权业务的入参 target_id。
     */
    val TARGET_ID = ""

    /**
     * pkcs8 格式的商户私钥。
     *
     *
     * 如下私钥，RSA2_PRIVATE 或者 RSA_PRIVATE 只需要填入一个，如果两个都设置了，本 Demo 将优先
     * 使用 RSA2_PRIVATE。RSA2_PRIVATE 可以保证商户交易在更加安全的环境下进行，建议商户使用
     * RSA2_PRIVATE。
     *
     *
     * 建议使用支付宝提供的公私钥生成工具生成和获取 RSA2_PRIVATE。
     * 工具地址：https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=106097&docType=1
     */
    val RSA2_PRIVATE =
        "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCYJYflUySpQ//IL3wxdS937UV3iUw2VFXSYfq60DjS3/m73nM23uddswvuRoO+822JuekiXbfvkmGWYXNdXKqAoempPIl+ADxEXqvYGioyMLqVqV1meVQkGfVSr+CxQ9rkmdkVaKWqqDrVeFcUlN9ceW8YLJiKhpBT6hhqFPh7pngLIm6EotQ3mMNZoRID4yXpu8p6Eo8468Xr7mQZhfqGkjnXUWlhewBItZWdQ9JcwEsWsRUtCmk/BbAO+H7NrVv2oWREIacoKD0Ws79cAmdhQwsDFjnC/5qkb9hZj1ahhlS2zzEp6rhxERiI63+ee6sRO/pPJoaTTBUST0kpUcL5AgMBAAECggEAZ6urHae5o1yiPVWd2lVvMtiKLRlwxNRSZjg9EG4xSf8zu7+n4gugu0f1KTcDLmnQibgUE0aovqWPuVhNs6AgzeWFwbtuNF0Us8GOdoHdnrV1beUpr1mc67yEXQNap28FCB+Mu/nCaLaY4DxPmcaXK/vSpzY7+qgWUBeC60W+ywFlk2CNeJBTSmUTZSWimSv/f3x2/7biMdr1o+TF+tykK+A5yfIEZYXf4birzjAwVjtDSsetYAjRyuM7oR00leOB+U/WauxL4GsVadhcM9VIS8W3DE9kQbbH8BT8nk9x1lfOCYMb5EyI6f97lucUmneK3uPd+9na5dh/EhO4jHfIAQKBgQDWB/8HQmmCWnbT+dTY7QFxllCDBx13z0xYaUjmBOYKVSz3ouQSwtxsAY0IgqPdV26oRL5FOCaW7s4Wdg8cqLXYGZHHJ5Aby9clNEzPfQ0aHY6UQiIO512LotVpF7IzSAAP22rYApfiK1hlgBLB4No3bMbPOXNeqP1Itvq3bL0c8QKBgQC1+wgQnpocmk9ZznTEJh2kTNaO7GlLRyatQ8GYUMfAcq1plmlnXJyHwpGuLUSEcHofh394IhL09qqVceDpgqlp1RIXgCoiFLuM/KXTF3OJD+SCwgR9rYZNhbPcY6P+Whx8ngXAHdPoZWjeMx2mtZTDZ6b99V5F6RiPwjpeAOmmiQKBgBXXew8il+HVmYrIVBBPH3aYAF9euoMfhIsBM49FsLQdPRmIZf4EJLpg7iOQMWjFI2XIniIyOL3uYNmp8qDaFrSW52mLgAlWI/6H98601EF2ArbeiNs8gS9ezqiK4oSZNGhp291vZlCOW9b/2uouKBa/4woCsuNWG4LwKWXOkv4BAoGACt2PMLbXisen3zvVevSvpmS0FtqEuurno0a9Y2PHWXU/Z2OErZg4/F4gpp6rTaENmZ5UfQ7DxP6JVtzyyd50UQ5YwzBy05AbVqKrH/xxeIiLY0dET2Cx+ST3hTwpyYEF3Gbu/vaI9YJAjavNpGuJE1W4AcfJtjDht4uoQn6ZdMkCgYEAyR+e/PfxPevjzGmIBLZ+ZXnR1SVlQwda4/GrUyllUWf7akTSLkT+VvkfbcHaHB2Vil8LFYt/SKteKPBy7l0YRuNq74FLZka6Y6OmmemHXRSqOJzcEGyrOWT5ElLmywMltQK4s0VXwTAtsForDE4eqmuz1rZ0Er4rsKdVpdu/I5A="
    val RSA_PRIVATE = ""

    private val SDK_PAY_FLAG = 1
    private val SDK_AUTH_FLAG = 2

    @SuppressLint("HandlerLeak")
    private val mHandler: Handler = object : Handler() {
        @Suppress("unused")
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                SDK_PAY_FLAG -> {
                    val payResult = PayResult(msg.obj as Map<String?, String?>)

                    /**
                     * 对于支付结果，请商户依赖服务端的异步通知结果。同步通知结果，仅作为支付结束的通知。
                     */
                    val resultInfo = payResult.result // 同步返回需要验证的信息
                    val resultStatus = payResult.resultStatus
                    // 判断resultStatus 为9000则代表支付成功
                    if (TextUtils.equals(resultStatus, "9000")) {
                        // 该笔订单是否真实支付成功，需要依赖服务端的异步通知。
//                        ToastUtils.showShort("支付成功");
                        Toast.makeText(this@PayActivity, "支付成功", Toast.LENGTH_SHORT).show()
                    } else {
                        // 该笔订单真实的支付结果，需要依赖服务端的异步通知。
//                        ToastUtils.showShort("支付失败" + payResult);
                        Toast.makeText(this@PayActivity, "支付成功", Toast.LENGTH_SHORT).show()
                        // 支付成功需要跳转到订单页面,同时保存订单信息
                        saveOrderAndJumpOrderAct()
                    }
                }

                else -> {}
            }
        }
    }

    //保存订单同时跳转到订单页面
    fun saveOrderAndJumpOrderAct() {
        val queryOrder = DatabaseUtil.getDb().orderDao().queryOrder()
        val orderList = mutableListOf<OrderPayBean>()
        queryOrder.forEach {
            //从待付款订单中拿到bean,赋值到已付款bean中
            val orderPayBean = OrderPayBean(
                it.count,
                it.goods_default_icon,
                it.goods_default_price,
                it.goods_desc,
                it.goods_id,
                it.id
            )
            orderList.add(orderPayBean)
        }
        DatabaseUtil.getDb().orderPayDao().insertOrderPay(orderList)

        val intent = Intent(this, OrderPayActivity::class.java)
        startActivity(intent)
    }


    /**
     * 支付宝支付业务示例
     */
    fun pay() {
        if (TextUtils.isEmpty(APPID) || TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE)) {
            return
        }

        /*
         * 这里只是为了方便直接向商户展示支付宝的整个支付流程；所以Demo中加签过程直接放在客户端完成；
         * 真实App里，privateKey等数据严禁放在客户端，加签过程务必要放在服务端完成；
         * 防止商户私密数据泄露，造成不必要的资金损失，及面临各种安全风险；
         *
         * orderInfo 的获取必须来自服务端；
         */
        val rsa2 = RSA2_PRIVATE.length > 0
        val params = OrderInfoUtil2_0.buildOrderParamMap(APPID, rsa2)
        val orderParam = OrderInfoUtil2_0.buildOrderParam(params)
        val privateKey = if (rsa2) RSA2_PRIVATE else RSA_PRIVATE
        val sign = OrderInfoUtil2_0.getSign(params, privateKey, rsa2)
        val orderInfo = "$orderParam&$sign"
        val payRunnable = Runnable {
            val alipay = PayTask(this)
            val result = alipay.payV2(orderInfo, true)
            Log.i("msp", result.toString())
            val msg = Message()
            msg.what = SDK_PAY_FLAG
            msg.obj = result
            mHandler.sendMessage(msg)
        }

        // 必须异步调用
        val payThread = Thread(payRunnable)
        payThread.start()
    }

}